package ws.performancetest.api;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import ws.performancetest.api.exception.InvalidTestConfiguration;

/**
 * This interface provides services to run a set of performance tests.
 * 
 * @author Wilson Santos, 36228 <wilson.santos@ua.pt>
 */
public interface TestSuite {

  /**
   * Get the cycle amount list.
   */
  Integer[] getCycleAmountList();

  /**
   * Set list of cycle amounts.
   * 
   * @param newList list with cycle amounts.
   */
  void setCycleAmountList(Integer[] newList);

  /**
   * Get the number of samples the test suite will save for each test.
   * Each test might be run several times to enhance statistical value of the
   * results.
   *
   * @return number of samples.
   */
  int getSamplesCount();

  /**
   * Set a new value for the number of test samples.
   * 
   * @param count new value.
   */
  void setSamplesCount(int count);

  /**
   * Get list of thread amounts to be created for each test.
   */
  Integer[] getThreadAmountList();

  /**
   * Set list of thread amounts to be created for each test.
   * 
   * For example, if {@code newList = (5, 10)} all tests on the suite will
   * first be run for 5 threads and then for 10 threads.
   * 
   * @param newList list with thread amounts.
   */
  void setThreadAmountList(Integer[] newList);

  /**
   * Get the number of test on this test suite.
   * 
   * @return number of test on this test suite.
   */
  int getTestCount();

  /**
   * Run all tests on the test suite.
   *
   * @throws SQLException if an database error occurred while saving test results.
   * @throws InterruptedException if interrupted while waiting for tests to finish.
   */
  void runAllTests() throws Exception;

  /**
   * Run the tests selected.
   * 
   * @param testList list with the selected tests to be run.
   *
   * @throws SQLException if an database error occurred while saving test results.
   * @throws InterruptedException if interrupted while waiting for tests to finish.
   */
  void runSelectedTests(List<Test> performanceTestList) throws Exception;

  /**
   * Write the current test results to the database.
   */
  void writeLogToDatabase() throws SQLException;

  /**
   * Write the current test results to a file.
   *
   * @throws IOException
   */
  void writeLogToFile() throws IOException;

  /**
   * Get a list with all performance tests on this test suite.
   *
   * @return list with all performance tests on this test suite.
   */
  List<Test> getTestList();

  /**
   * Check if the test suites on the list have previous results.
   *
   * @param testList test suites to be checked.
   *
   * @return {@code true} if there's previous results, otherwise {@code false}.
   *
   * @throws SQLException if an database error occurred while checking for previous results.
   */
  boolean hasPreviousResults(List<Test> testList) throws SQLException;

  /**
   * Remove the previous results for the test suite list.
   *
   * @param testList list of test suites whose results will be erased.
   *
   * @throws SQLException if an database error occurred while erasing results.
   */
  void removePreviousResults(List<Test> testList) throws SQLException;

  /**
   * Save configuration from the test suite properties into database.
   * 
   * @throws SQLException if an database error occurred while retrieving the configuration.
   */
  void saveConfiguration() throws SQLException, InvalidTestConfiguration;

  /**
   * Load configuration from database into the test suite properties.
   *
   * @return {@code true} if configuration was found and loaded, otherwise {@code false}.
   * 
   * @throws SQLException if an database error occurred while retrieving the configuration.
   */
  boolean loadConfiguration() throws SQLException;

  /**
   * Interrupt the ongoing test suite.
   */
  void interrupt();

  /**
   * Get the number of cycle count elements on the cycle count list.
   * 
   * @return number of elements on the list.
   */
  public int getCycleCount();

  /**
   * Get the number of thread amount elements on the thread amount list.
   * 
   * @return number of elements on the list.
   */
  public int getThreadCount();

  public void setDBUrl(String url);

  public void addLog(String name, long time);
}
